package com.smart.community.user.controller;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.smart.community.commons.annotation.ApiLog;
import com.smart.community.commons.constant.MessageConstants;
import com.smart.community.commons.enums.ApiLogOperationType;
import com.smart.community.commons.result.PageResult;
import com.smart.community.commons.result.Result;
import com.smart.community.commons.utils.SecurityUtils;
import com.smart.community.user.dto.UserDTO;
import com.smart.community.user.dto.UserQueryDTO;
import com.smart.community.user.dto.UserProfileUpdateDTO;
import com.smart.community.user.entity.LoginLog;
import com.smart.community.user.entity.User;
import com.smart.community.user.entity.UserUploadFile;
import com.smart.community.user.service.LoginLogService;
import com.smart.community.user.service.UserService;
import com.smart.community.user.service.UserUploadFileService;
import com.smart.community.user.vo.UserRoleAssignVO;
import com.smart.community.user.vo.UserUploadFileVO;
import com.smart.community.user.vo.UserVO;

import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;

/**
 * 用户管理控制器
 * 
 * @author Wu.Liang
 * @since 2024-12-21
 * @version 1.0.0
 */
@Slf4j
@RestController
@RequestMapping("/user")
@Tag(name = "用户管理", description = "用户管理相关接口")
@Validated
public class UserController {

    @Autowired
    private UserService userService;
    
    @Autowired
    private LoginLogService loginLogService;

    @Autowired
    private UserUploadFileService userUploadFileService;

    // 注意：用户登录登出功能已在AuthController中实现，此处移除重复实现

    /**
     * 分页查询用户列表
     * 
     * @param queryDTO 查询条件
     * @return 用户列表
     * @throws Exception 统一异常
     */
    @GetMapping("/list")
    @SaCheckPermission("user:menu")
    public Result<PageResult<UserVO>> getUserList(@Valid UserQueryDTO queryDTO) throws Exception {
        // 直接调用Service，异常统一抛出，不捕获处理
        IPage<User> userPage = userService.getUserPage(queryDTO);
        
        // 转换为PageResult<UserVO>
        List<UserVO> userVOList = new ArrayList<>();
        for (User user : userPage.getRecords()) {
            UserVO userVO = new UserVO();
            userVO.setId(user.getId());
            userVO.setUsername(user.getUsername());
            userVO.setRealName(user.getRealName());
            userVO.setPhone(user.getPhone());
            userVO.setEmail(user.getEmail());
            userVO.setAvatar(user.getAvatar());
            userVO.setStatus(user.getStatus());
            userVO.setUserType(user.getUserType());
            userVO.setCreateTime(user.getCreateTime());
            userVO.setUpdateTime(user.getUpdateTime());
            userVOList.add(userVO);
        }
        
        PageResult<UserVO> pageResult = new PageResult<>();
        pageResult.setRecords(userVOList);
        pageResult.setTotal(userPage.getTotal());
        pageResult.setSize((int) userPage.getSize());
        pageResult.setCurrent((int) userPage.getCurrent());
        pageResult.setPages((int) userPage.getPages());
        
        return Result.success(pageResult);
    }

    /**
     * 根据ID查询用户
     * 
     * @param userId 用户ID
     * @return 用户信息
     * @throws Exception 统一异常
     */
    @GetMapping("/detail/{userId}")
    @SaCheckPermission("user:menu")
    public Result<UserVO> getUserById(@PathVariable Long userId) throws Exception {
        // 直接调用Service，异常统一抛出，不捕获处理
        User user = userService.getById(userId);
        if (user == null) {
            return Result.fail("用户不存在");
        }
        
        UserVO userVO = new UserVO();
        userVO.setId(user.getId());
        userVO.setUsername(user.getUsername());
        userVO.setNickname(user.getNickname());
        userVO.setRealName(user.getRealName());
        userVO.setPhone(user.getPhone());
        userVO.setEmail(user.getEmail());
        userVO.setAvatar(user.getAvatar());
        userVO.setGender(user.getGender());
        userVO.setBirthday(user.getBirthday());
        userVO.setIdCard(user.getIdCard());
        userVO.setAddress(user.getAddress());
        userVO.setUserType(user.getUserType());
        userVO.setStatus(user.getStatus());
        userVO.setAuditStatus(user.getAuditStatus());
        userVO.setIsAdminProtected(user.getIsAdminProtected());
        userVO.setLastLoginTime(user.getLastLoginTime());
        userVO.setLastLoginIp(user.getLastLoginIp());
        userVO.setLoginFailCount(user.getLoginFailCount());
        userVO.setLockTime(user.getLockTime());
        userVO.setOrganizationId(user.getOrganizationId());
        userVO.setPropertyCompanyId(user.getPropertyCompanyId());
        userVO.setCommunityId(user.getCommunityId());
        userVO.setBuildingId(user.getBuildingId());
        userVO.setUnitId(user.getUnitId());
        userVO.setHouseholdId(user.getHouseholdId());
        userVO.setCreateTime(user.getCreateTime());
        userVO.setUpdateTime(user.getUpdateTime());
        
        // 设置状态名称
        if (user.getStatus() != null) {
            switch (user.getStatus()) {
                case 0:
                    userVO.setStatusName("禁用");
                    break;
                case 1:
                    userVO.setStatusName("启用");
                    break;
                case 2:
                    userVO.setStatusName("待审核");
                    break;
                case 3:
                    userVO.setStatusName("锁定");
                    break;
                default:
                    userVO.setStatusName("未知");
            }
        }
        
        // 设置审核状态名称
        if (user.getAuditStatus() != null) {
            switch (user.getAuditStatus()) {
                case 0:
                    userVO.setAuditStatusName("待审核");
                    break;
                case 1:
                    userVO.setAuditStatusName("审核通过");
                    break;
                case 2:
                    userVO.setAuditStatusName("审核拒绝");
                    break;
                default:
                    userVO.setAuditStatusName("未知");
            }
        }
        
        // 设置用户类型名称
        if (user.getUserType() != null) {
            switch (user.getUserType()) {
                case "SUPER_ADMIN":
                    userVO.setUserTypeName("超级管理员");
                    break;
                case "PROPERTY_ADMIN":
                    userVO.setUserTypeName("物业管理员");
                    break;
                case "COMMUNITY_ADMIN":
                    userVO.setUserTypeName("社区管理员");
                    break;
                case "BUILDING_ADMIN":
                    userVO.setUserTypeName("楼栋管理员");
                    break;
                case "UNIT_ADMIN":
                    userVO.setUserTypeName("单元管理员");
                    break;
                case "HOUSEHOLD_ADMIN":
                    userVO.setUserTypeName("房户管理员");
                    break;
                case "NORMAL_USER":
                    userVO.setUserTypeName("普通用户");
                    break;
                default:
                    userVO.setUserTypeName("未知");
            }
        }
        
        return Result.success(userVO);
    }

    /**
     * 根据ID查询用户信息（Feign接口）
     * 
     * @param userId 用户ID
     * @return 用户信息DTO
     * @throws Exception 统一异常
     */
    @GetMapping("/info/{userId}")
    public Result<UserDTO> getUserInfoById(@PathVariable Long userId) throws Exception {
        // 直接调用Service，异常统一抛出，不捕获处理
        User user = userService.getById(userId);
        if (user == null) {
            return Result.fail("用户不存在");
        }
        
        // 转换为UserDTO
        UserDTO userDTO = new UserDTO();
        userDTO.setId(user.getId());
        userDTO.setUsername(user.getUsername());
        userDTO.setRealName(user.getRealName());
        userDTO.setPhone(user.getPhone());
        userDTO.setEmail(user.getEmail());
        userDTO.setAvatar(user.getAvatar());
        userDTO.setStatus(user.getStatus());
        // 根据用户类型字符串转换为对应的Integer值
        Integer userTypeValue = convertUserTypeToInteger(user.getUserType());
        userDTO.setUserType(userTypeValue);
        
        return Result.success(userDTO);
    }

    /**
     * 创建用户
     * 
     * @param user 用户信息
     * @return 创建结果
     * @throws Exception 统一异常
     */
    @ApiLog(
        logTitle = "创建用户",
        logType = 2,
        moduleName = "用户管理",
        operationType = ApiLogOperationType.ADD
    )
    @PostMapping
    @SaCheckPermission("user:menu")
    public Result<Void> createUser(@Valid @RequestBody User user) throws Exception {
        // 直接调用Service，异常统一抛出，不捕获处理
        UserDTO userDTO = new UserDTO();
        userDTO.setId(user.getId());
        userDTO.setUsername(user.getUsername());
        userDTO.setRealName(user.getRealName());
        userDTO.setPhone(user.getPhone());
        userDTO.setEmail(user.getEmail());
        userDTO.setAvatar(user.getAvatar());
        userDTO.setStatus(user.getStatus());
        // 根据用户类型字符串转换为对应的Integer值
        Integer userTypeValue = convertUserTypeToInteger(user.getUserType());
        userDTO.setUserType(userTypeValue);
        userService.createUser(userDTO);
        return Result.success();
    }

    /**
     * 更新用户
     * 
     * @param user 用户信息
     * @return 更新结果
     * @throws Exception 统一异常
     */
    @ApiLog(
        logTitle = "更新用户",
        logType = 2,
        moduleName = "用户管理",
        operationType = ApiLogOperationType.UPDATE
    )
    @PutMapping
    @SaCheckPermission("user:menu")
    public Result<Void> updateUser(@Valid @RequestBody User user) throws Exception {
        // 直接调用Service，异常统一抛出，不捕获处理
        UserDTO userDTO = new UserDTO();
        userDTO.setId(user.getId());
        userDTO.setUsername(user.getUsername());
        userDTO.setRealName(user.getRealName());
        userDTO.setPhone(user.getPhone());
        userDTO.setEmail(user.getEmail());
        userDTO.setAvatar(user.getAvatar());
        userDTO.setStatus(user.getStatus());
        // 根据用户类型字符串转换为对应的Integer值
        Integer userTypeValue = convertUserTypeToInteger(user.getUserType());
        userDTO.setUserType(userTypeValue);
        userService.updateUser(userDTO);
        return Result.success();
    }

    /**
     * 删除用户
     * 
     * @param userId 用户ID
     * @return 删除结果
     * @throws Exception 统一异常
     */
    @ApiLog(
        logTitle = "删除用户",
        logType = 2,
        moduleName = "用户管理",
        operationType = ApiLogOperationType.DELETE
    )
    @DeleteMapping("/delete/{userId}")
    @SaCheckPermission("user:menu")
    public Result<Void> deleteUser(@PathVariable Long userId) throws Exception {
        // 直接调用Service，异常统一抛出，不捕获处理
        userService.deleteUser(userId);
        return Result.success();
    }

    /**
     * 批量删除用户
     * 
     * @param userIds 用户ID列表
     * @return 删除结果
     * @throws Exception 统一异常
     */
    @ApiLog(
        logTitle = "批量删除用户",
        logType = 2,
        moduleName = "用户管理",
        operationType = ApiLogOperationType.DELETE
    )
    @DeleteMapping("/batch")
    @SaCheckPermission("user:menu")
    public Result<Void> batchDeleteUsers(@RequestBody List<Long> userIds) throws Exception {
        // 直接调用Service，异常统一抛出，不捕获处理
        userService.batchDeleteUsers(userIds);
        return Result.success();
    }

    /**
     * 重置密码
     * 
     * @param userId 用户ID
     * @param newPassword 新密码
     * @return 重置结果
     * @throws Exception 统一异常
     */
    @ApiLog(
        logTitle = "重置用户密码",
        logType = 2,
        moduleName = "用户管理",
        operationType = ApiLogOperationType.UPDATE
    )
    @PostMapping("/password/reset/{userId}")
    public Result<Void> resetPassword(@PathVariable Long userId, @RequestParam String newPassword) throws Exception {
        // 直接调用Service，异常统一抛出，不捕获处理
        userService.resetPassword(userId, newPassword);
        return Result.success();
    }

    /**
     * 移动端更新用户个人资料
     * 
     * @param updateDTO 更新信息
     * @return 更新结果
     * @throws Exception 统一异常
     */
    @ApiLog(
        logTitle = "移动端更新用户个人资料",
        logType = 2,
        moduleName = "用户管理",
        operationType = ApiLogOperationType.UPDATE
    )
    @PutMapping("/mobile/profile/update")
    @Operation(summary = "移动端更新用户信息", description = "移动端用户更新个人资料信息")
    public Result<UserVO> mobileUpdateUserProfile(@Valid @RequestBody UserProfileUpdateDTO updateDTO) throws Exception {
        try {
            // 获取当前用户ID
            Long userId = SecurityUtils.getCurrentUserId();
            
            // 参数验证
            if (updateDTO == null) {
                return Result.fail("更新信息不能为空");
            }
            
            // 业务处理
            UserVO userVO = userService.updateUserProfile(userId, updateDTO);
            
            // 记录操作日志
            log.info("移动端用户信息更新成功，用户ID: {}", userId);
            
            return Result.success("更新成功", userVO);
        } catch (Exception e) {
            log.error("移动端用户信息更新失败，用户ID: {}", SecurityUtils.getCurrentUserId(), e);
            return Result.fail("更新失败：" + e.getMessage());
        }
    }

    /**
     * Web端更新当前用户个人资料
     * 
     * @param updateDTO 更新信息
     * @return 更新结果
     * @throws Exception 统一异常
     */
    @ApiLog(
        logTitle = "Web端更新用户个人资料",
        logType = 2,
        moduleName = "用户管理",
        operationType = ApiLogOperationType.UPDATE
    )
    @PutMapping("/users/profile/update")
    @Operation(summary = "Web端更新用户信息", description = "Web端用户更新个人资料信息")
    public Result<UserVO> updateCurrentUserProfile(@Valid @RequestBody UserProfileUpdateDTO updateDTO) throws Exception {
        try {
            // 获取当前用户ID
            Long userId = SecurityUtils.getCurrentUserId();
            
            // 参数验证
            if (updateDTO == null) {
                return Result.fail("更新信息不能为空");
            }
            
            // 业务处理
            UserVO userVO = userService.updateUserProfile(userId, updateDTO);
            
            // 记录操作日志
            log.info("Web端用户信息更新成功，用户ID: {}", userId);
            
            return Result.success("更新成功", userVO);
        } catch (Exception e) {
            log.error("Web端用户信息更新失败，用户ID: {}", SecurityUtils.getCurrentUserId(), e);
            return Result.fail("更新失败：" + e.getMessage());
        }
    }

    /**
     * 修改密码
     * 
     * @param userId 用户ID
     * @param oldPassword 旧密码
     * @param newPassword 新密码
     * @return 修改结果
     */
    @ApiLog(
        logTitle = "修改用户密码",
        logType = 2,
        moduleName = "用户管理",
        operationType = ApiLogOperationType.UPDATE
    )
    @PostMapping("/password/change/{userId}")
    public Result<Void> changePassword(@PathVariable Long userId, 
                                     @RequestParam String oldPassword, 
                                     @RequestParam String newPassword) {
        try {
            log.info("开始修改用户密码，用户ID: {}", userId);
            
            userService.changePassword(userId, oldPassword, newPassword);
            
            log.info("用户密码修改成功，用户ID: {}", userId);
            return Result.success();
        } catch (Exception e) {
            log.error("修改用户密码失败，用户ID: {}, 错误信息: {}", userId, e.getMessage(), e);
            return Result.fail("修改密码失败：" + e.getMessage());
        }
    }

    /**
     * 启用用户
     * 
     * @param userId 用户ID
     * @return 启用结果
     * @throws Exception 统一异常
     */
    @ApiLog(
        logTitle = "启用用户",
        logType = 2,
        moduleName = "用户管理",
        operationType = ApiLogOperationType.UPDATE
    )
    @PostMapping("/status/enable/{userId}")
    public Result<Void> enableUser(@PathVariable Long userId) throws Exception {
        // 直接调用Service，异常统一抛出，不捕获处理
        userService.enableUser(userId);
        return Result.success();
    }

    /**
     * 禁用用户
     * 
     * @param userId 用户ID
     * @return 禁用结果
     * @throws Exception 统一异常
     */
    @ApiLog(
        logTitle = "禁用用户",
        logType = 2,
        moduleName = "用户管理",
        operationType = ApiLogOperationType.UPDATE
    )
    @PostMapping("/status/disable/{userId}")
    public Result<Void> disableUser(@PathVariable Long userId) throws Exception {
        // 直接调用Service，异常统一抛出，不捕获处理
        userService.disableUser(userId);
        return Result.success();
    }

    /**
     * 锁定用户
     * 
     * @param userId 用户ID
     * @return 锁定结果
     * @throws Exception 统一异常
     */
    @ApiLog(
        logTitle = "锁定用户",
        logType = 2,
        moduleName = "用户管理",
        operationType = ApiLogOperationType.UPDATE
    )
    @PostMapping("/status/lock/{userId}")
    public Result<Void> lockUser(@PathVariable Long userId) throws Exception {
        // 直接调用Service，异常统一抛出，不捕获处理
        userService.lockUser(userId);
        return Result.success();
    }

    /**
     * 解锁用户
     * 
     * @param userId 用户ID
     * @return 解锁结果
     * @throws Exception 统一异常
     */
    @ApiLog(
        logTitle = "解锁用户",
        logType = 2,
        moduleName = "用户管理",
        operationType = ApiLogOperationType.UPDATE
    )
    @PostMapping("/status/unlock/{userId}")
    public Result<Void> unlockUser(@PathVariable Long userId) throws Exception {
        // 直接调用Service，异常统一抛出，不捕获处理
        userService.unlockUser(userId);
        return Result.success();
    }

    /**
     * 获取用户角色分配信息
     * 
     * @param userId 用户ID
     * @return 用户角色分配信息
     */
    @GetMapping("/role/assign/{userId}")
    @Operation(summary = "获取用户角色分配信息", description = "获取用户信息和可用角色列表")
    @SaCheckPermission("user:menu")
    public Result<UserRoleAssignVO> getUserRoleAssignInfo(@PathVariable Long userId) {
        try {
            log.info("获取用户角色分配信息，用户ID：{}", userId);
            UserRoleAssignVO userRoleAssignInfo = userService.getUserRoleAssignInfo(userId);
            return Result.success(MessageConstants.QUERY_SUCCESS, userRoleAssignInfo);
        } catch (Exception e) {
            log.error("获取用户角色分配信息失败，用户ID：{}", userId, e);
            return Result.error(MessageConstants.QUERY_FAILED);
        }
    }

    /**
     * 分配角色接口
     * 
     * <b>接口说明：</b> 为指定用户分配角色，支持单角色或多角色分配。
     * 
     * <b>请求方式：</b> POST
     * <b>请求路径：</b> /user/role/assign/{userId}
     * 
     * <b>路径参数：</b>
     *   - userId (Long)：用户ID，必填
     * 
     * <b>请求体：</b> 直接传递Long数组（application/json）
     * <pre>
     * [1, 2, 3]
     * </pre>
     * 
     * <b>请求示例：</b>
     * POST /user/role/assign/1001
     * Body:
     * [2, 3]
     * 
     * <b>响应体：</b> 标准响应结构
     * <pre>
     * {
     *   "code": 0,
     *   "message": "操作成功",
     *   "data": null
     * }
     * </pre>
     * 
     * <b>错误码：</b>
     *   - 40001: 参数校验失败
     *   - 40002: 用户不存在
     *   - 40003: 角色不存在
     *   - 50000: 系统异常
     * 
     * <b>注意事项：</b>
     *   - 请求体必须为Long数组，不能为对象或嵌套结构。
     *   - 前后端参数类型、格式必须严格一致。
     *   - 详见《智慧社区微服务架构总览.md》接口设计规范。
     */
    @ApiLog(
        logTitle = "分配用户角色",
        logType = 2,
        moduleName = "用户管理",
        operationType = ApiLogOperationType.UPDATE
    )
    @PostMapping("/role/assign/{userId}")
    public Result<Void> assignRoles(@PathVariable Long userId, @RequestBody List<Long> roleIds) throws Exception {
        // 直接调用Service，异常统一抛出，不捕获处理
        userService.assignRoles(userId, roleIds);
        return Result.success();
    }

    /**
     * 获取用户角色列表
     * 
     * @param userId 用户ID
     * @return 角色列表
     */
    @GetMapping("/role/list/{userId}")
    public Result<List<Map<String, Object>>> getUserRoles(@PathVariable Long userId) {
        try {
            List<Map<String, Object>> roles = userService.getUserRoles(userId);
            return Result.success(roles);
        } catch (Exception e) {
            log.error("获取用户角色失败: {}", e.getMessage(), e);
            return Result.fail("获取失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户菜单列表
     * 
     * @param userId 用户ID
     * @return 菜单列表
     */
    @GetMapping("/menu/list/{userId}")
    public Result<List<Map<String, Object>>> getUserMenus(@PathVariable Long userId) {
        try {
            List<Map<String, Object>> menus = userService.getUserMenus(userId);
            return Result.success(menus);
        } catch (Exception e) {
            log.error("获取用户菜单失败: {}", e.getMessage(), e);
            return Result.fail("获取失败: " + e.getMessage());
        }
    }

    /**
     * 检查用户名是否存在
     * 
     * @param username 用户名
     * @return 检查结果
     */
    @GetMapping("/check-username")
    public Result<Boolean> checkUsernameExists(@RequestParam String username) {
        try {
            boolean exists = userService.checkUsernameExists(username);
            return Result.success(exists);
        } catch (Exception e) {
            log.error("检查用户名失败: {}", e.getMessage(), e);
            return Result.fail("检查失败: " + e.getMessage());
        }
    }

    /**
     * 检查手机号是否存在
     * 
     * @param phone 手机号
     * @return 检查结果
     */
    @GetMapping("/check-phone")
    public Result<Boolean> checkPhoneExists(@RequestParam String phone) {
        try {
            boolean exists = userService.checkPhoneExists(phone);
            return Result.success(exists);
        } catch (Exception e) {
            log.error("检查手机号失败: {}", e.getMessage(), e);
            return Result.fail("检查失败: " + e.getMessage());
        }
    }

    /**
     * 检查邮箱是否存在
     * 
     * @param email 邮箱
     * @return 检查结果
     */
    @GetMapping("/check-email")
    public Result<Boolean> checkEmailExists(@RequestParam String email) {
        try {
            boolean exists = userService.checkEmailExists(email);
            return Result.success(exists);
        } catch (Exception e) {
            log.error("检查邮箱失败: {}", e.getMessage(), e);
            return Result.fail("检查失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户登录历史
     * 
     * @param userId 用户ID
     * @param limit 限制数量，默认5
     * @return 登录历史
     */
    @GetMapping("/login/history/{userId}")
    @Operation(summary = "获取用户登录历史", description = "获取用户最近5次登录记录")
    @SaCheckPermission("user:menu")
    public Result<List<LoginLog>> getUserLoginHistory(
            @PathVariable @NotNull(message = "用户ID不能为空") Long userId,
            @RequestParam(required = false, defaultValue = "5") Integer limit) {
        try {
            log.info("获取用户登录历史，用户ID：{}，限制数量：{}", userId, limit);
            
            List<LoginLog> loginLogs = loginLogService.getRecentLoginLogs(userId, limit);
            
            return Result.success(MessageConstants.QUERY_SUCCESS, loginLogs);
            
        } catch (Exception e) {
            log.error("获取用户登录历史失败，用户ID：{}", userId, e);
            return Result.error(MessageConstants.QUERY_FAILED);
        }
    }

    /**
     * 检查用户名唯一性
     * 
     * @param username 用户名
     * @param excludeUserId 排除的用户ID（更新时使用）
     * @return 是否唯一
     */
    @GetMapping("/check/username")
    @Operation(summary = "检查用户名唯一性", description = "检查用户名是否已存在")
    @SaCheckPermission("user:menu")
    public Result<Boolean> checkUsernameUnique(
            @RequestParam @NotNull(message = "用户名不能为空") String username,
            @RequestParam(required = false) Long excludeUserId) {
        try {
            log.info("检查用户名唯一性，用户名：{}，排除用户ID：{}", username, excludeUserId);
            
            boolean isUnique = userService.checkUsernameUnique(username, excludeUserId);
            
            return Result.success(MessageConstants.QUERY_SUCCESS, isUnique);
            
        } catch (Exception e) {
            log.error("检查用户名唯一性失败，用户名：{}", username, e);
            return Result.error(MessageConstants.QUERY_FAILED);
        }
    }

    /**
     * 检查手机号唯一性
     * 
     * @param phone 手机号
     * @param excludeUserId 排除的用户ID（更新时使用）
     * @return 是否唯一
     */
    @GetMapping("/check/phone")
    @Operation(summary = "检查手机号唯一性", description = "检查手机号是否已存在")
    @SaCheckPermission("user:menu")
    public Result<Boolean> checkPhoneUnique(
            @RequestParam @NotNull(message = "手机号不能为空") String phone,
            @RequestParam(required = false) Long excludeUserId) {
        try {
            log.info("检查手机号唯一性，手机号：{}，排除用户ID：{}", phone, excludeUserId);
            
            boolean isUnique = userService.checkPhoneUnique(phone, excludeUserId);
            
            return Result.success(MessageConstants.QUERY_SUCCESS, isUnique);
            
        } catch (Exception e) {
            log.error("检查手机号唯一性失败，手机号：{}", phone, e);
            return Result.error(MessageConstants.QUERY_FAILED);
        }
    }

    /**
     * 检查邮箱唯一性
     * 
     * @param email 邮箱
     * @param excludeUserId 排除的用户ID（更新时使用）
     * @return 是否唯一
     */
    @GetMapping("/check/email")
    @Operation(summary = "检查邮箱唯一性", description = "检查邮箱是否已存在")
    @SaCheckPermission("user:menu")
    public Result<Boolean> checkEmailUnique(
            @RequestParam @NotNull(message = "邮箱不能为空") String email,
            @RequestParam(required = false) Long excludeUserId) {
        try {
            log.info("检查邮箱唯一性，邮箱：{}，排除用户ID：{}", email, excludeUserId);
            
            boolean isUnique = userService.checkEmailUnique(email, excludeUserId);
            
            return Result.success(MessageConstants.QUERY_SUCCESS, isUnique);
            
        } catch (Exception e) {
            log.error("检查邮箱唯一性失败，邮箱：{}", email, e);
            return Result.error(MessageConstants.QUERY_FAILED);
        }
    }

    /**
     * 检查身份证号唯一性
     * 
     * @param idCard 身份证号
     * @param excludeUserId 排除的用户ID（更新时使用）
     * @return 是否唯一
     */
    @GetMapping("/check/idcard")
    @Operation(summary = "检查身份证号唯一性", description = "检查身份证号是否已存在")
    @SaCheckPermission("user:menu")
    public Result<Boolean> checkIdCardUnique(
            @RequestParam @NotNull(message = "身份证号不能为空") String idCard,
            @RequestParam(required = false) Long excludeUserId) {
        try {
            log.info("检查身份证号唯一性，身份证号：{}，排除用户ID：{}", idCard, excludeUserId);
            
            boolean isUnique = userService.checkIdCardUnique(idCard, excludeUserId);
            
            return Result.success(MessageConstants.QUERY_SUCCESS, isUnique);
            
        } catch (Exception e) {
            log.error("检查身份证号唯一性失败，身份证号：{}", idCard, e);
            return Result.error(MessageConstants.QUERY_FAILED);
        }
    }

    /**
     * 物业公司人员新增
     * 
     * @param userData 用户信息
     * @return 新增结果
     */
    @ApiLog(
        logTitle = "新增物业公司用户",
        logType = 2,
        moduleName = "用户管理",
        operationType = ApiLogOperationType.ADD
    )
    @PostMapping("/property-company/add")
    @Operation(summary = "物业公司人员新增", description = "为物业公司新增用户账号")
    @SaCheckPermission("user:menu")
    public Result<Void> addPropertyCompanyUser(@RequestBody Map<String, Object> userData) throws Exception {
        // 直接调用Service，异常统一抛出，不捕获处理
        userService.addPropertyCompanyUser(userData);
        return Result.success();
    }

    /**
     * 获取物业公司用户列表
     * 
     * @param propertyCompanyId 物业公司ID
     * @param current 当前页
     * @param size 页大小
     * @return 用户列表
     * @throws Exception 
     */
    @GetMapping("/property-company/{propertyCompanyId}/users")
    @Operation(summary = "获取物业公司用户列表", description = "获取指定物业公司的用户列表")
    @SaCheckPermission("user:menu")
    public Result<PageResult<UserVO>> getPropertyCompanyUsers(
            @PathVariable Long propertyCompanyId,
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "10") Integer size) throws Exception {
            PageResult<UserVO> page = userService.getPropertyCompanyUsers(propertyCompanyId, current, size);
            return Result.success(page);
    }

    /**
     * 启用物业公司用户
     * 
     * @param userId 用户ID
     * @return 操作结果
     */
    @ApiLog(
        logTitle = "启用物业公司用户",
        logType = 2,
        moduleName = "用户管理",
        operationType = ApiLogOperationType.UPDATE
    )
    @PutMapping("/property-company/users/{userId}/enable")
    @Operation(summary = "启用物业公司用户", description = "启用指定物业公司的用户")
    @SaCheckPermission("user:menu")
    public Result<Void> enablePropertyCompanyUser(@PathVariable Long userId) throws Exception {
        // 直接调用Service，异常统一抛出，不捕获处理
        userService.enablePropertyCompanyUser(userId);
        return Result.success();
    }

    /**
     * 禁用物业公司用户
     * 
     * @param userId 用户ID
     * @return 操作结果
     */
    @ApiLog(
        logTitle = "禁用物业公司用户",
        logType = 2,
        moduleName = "用户管理",
        operationType = ApiLogOperationType.UPDATE
    )
    @PutMapping("/property-company/users/{userId}/disable")
    @Operation(summary = "禁用物业公司用户", description = "禁用指定物业公司的用户")
    @SaCheckPermission("user:menu")
    public Result<Void> disablePropertyCompanyUser(@PathVariable Long userId) throws Exception {
        // 直接调用Service，异常统一抛出，不捕获处理
        userService.disablePropertyCompanyUser(userId);
        return Result.success();
    }

    /**
     * 重置物业公司用户密码
     * 
     * @param userId 用户ID
     * @return 操作结果
     */
    @ApiLog(
        logTitle = "重置物业公司用户密码",
        logType = 2,
        moduleName = "用户管理",
        operationType = ApiLogOperationType.UPDATE
    )
    @PutMapping("/property-company/users/{userId}/reset-password")
    @Operation(summary = "重置物业公司用户密码", description = "重置指定物业公司用户的密码为默认密码")
    @SaCheckPermission("user:menu")
    public Result<Void> resetPropertyCompanyUserPassword(@PathVariable Long userId) throws Exception {
        // 直接调用Service，异常统一抛出，不捕获处理
        userService.resetPropertyCompanyUserPassword(userId);
        return Result.success();
    }
    
    /**
     * 将用户类型字符串转换为Integer值
     * 
     * @param userType 用户类型字符串
     * @return 用户类型Integer值
     */
    private Integer convertUserTypeToInteger(String userType) {
        if (userType == null) {
            return 3; // 默认为普通用户
        }
        
        switch (userType) {
            case "SUPER_ADMIN":
                return 1; // 超级管理员
            case "PROPERTY_ADMIN":
            case "COMMUNITY_ADMIN":
                return 2; // 管理员
            case "BUILDING_ADMIN":
            case "UNIT_ADMIN":
            case "HOUSEHOLD_ADMIN":
                return 2; // 管理员
            case "NORMAL_USER":
            default:
                return 3; // 普通用户
        }
    }

    // ==================== 文件上传相关接口 ====================

    /**
     * 上传文件
     * 
     * @param file 文件
     * @param uploadType 上传类型
     * @param uploadSource 上传来源
     * @return 文件信息
     * @throws Exception 统一异常
     */
    @ApiLog(
        logTitle = "上传文件",
        logType = 2,
        moduleName = "用户管理",
        operationType = ApiLogOperationType.ADD
    )
    @PostMapping("/upload")
    @Operation(summary = "上传文件", description = "用户上传文件到MinIO存储")
    public Result<UserUploadFileVO> uploadFile(
            @RequestParam("file") MultipartFile file,
            @RequestParam("uploadType") String uploadType,
            @RequestParam(value = "uploadSource", required = false, defaultValue = "WEB") String uploadSource) throws Exception {
        // 获取当前用户ID
        Long currentUserId = SecurityUtils.getCurrentUserId();
        // 直接调用Service，异常统一抛出，不捕获处理
        UserUploadFile uploadFile = userUploadFileService.uploadFile(file, currentUserId, uploadType, uploadSource);
        
        // 转换为VO
        UserUploadFileVO fileVO = convertToVO(uploadFile);
        return Result.success(fileVO);
    }

    /**
     * 获取文件信息
     * 
     * @param fileId 文件ID
     * @return 文件信息
     * @throws Exception 统一异常
     */
    @GetMapping("/file/{fileId}")
    @Operation(summary = "获取文件信息", description = "根据文件ID获取文件详细信息")
    @SaCheckPermission("user:menu")
    public Result<UserUploadFileVO> getFileInfo(@PathVariable Long fileId) throws Exception {
        // 直接调用Service，异常统一抛出，不捕获处理
        UserUploadFile uploadFile = userUploadFileService.getById(fileId);
        if (uploadFile == null) {
            return Result.fail("文件不存在");
        }
        
        // 转换为VO
        UserUploadFileVO fileVO = convertToVO(uploadFile);
        return Result.success(fileVO);
    }

    /**
     * 删除文件
     * 
     * @param fileId 文件ID
     * @return 删除结果
     * @throws Exception 统一异常
     */
    @ApiLog(
        logTitle = "删除文件",
        logType = 2,
        moduleName = "用户管理",
        operationType = ApiLogOperationType.DELETE
    )
    @DeleteMapping("/file/{fileId}")
    @Operation(summary = "删除文件", description = "删除用户上传的文件")
    @SaCheckPermission("user:menu")
    public Result<Void> deleteFile(@PathVariable Long fileId) throws Exception {
        // 获取当前用户ID
        Long currentUserId = SecurityUtils.getCurrentUserId();
        // 直接调用Service，异常统一抛出，不捕获处理
        userUploadFileService.deleteFile(fileId, currentUserId);
        return Result.success();
    }

    /**
     * 获取用户文件列表
     * 
     * @param userId 用户ID
     * @param uploadType 上传类型
     * @return 文件列表
     * @throws Exception 统一异常
     */
    @GetMapping("/files")
    @Operation(summary = "获取用户文件列表", description = "获取当前用户的文件列表")
    @SaCheckPermission("user:menu")
    public Result<java.util.List<UserUploadFileVO>> getUserFiles(
            @RequestParam(value = "uploadType", required = false) String uploadType) throws Exception {
        // 获取当前用户ID
        Long currentUserId = SecurityUtils.getCurrentUserId();
        // 直接调用Service，异常统一抛出，不捕获处理
        java.util.List<UserUploadFile> fileList;
        if (uploadType != null && !uploadType.isEmpty()) {
            fileList = userUploadFileService.getFilesByUserIdAndType(currentUserId, uploadType);
        } else {
            fileList = userUploadFileService.getFilesByUserId(currentUserId);
        }
        
        // 转换为VO列表
        java.util.List<UserUploadFileVO> voList = fileList.stream()
            .map(this::convertToVO)
            .collect(java.util.stream.Collectors.toList());
        return Result.success(voList);
    }



    /**
     * 将UserUploadFile转换为UserUploadFileVO
     * 
     * @param uploadFile 上传文件实体
     * @return 上传文件VO
     */
    private UserUploadFileVO convertToVO(UserUploadFile uploadFile) {
        if (uploadFile == null) {
            return null;
        }
        
        UserUploadFileVO vo = new UserUploadFileVO();
        vo.setId(uploadFile.getId());
        vo.setUserId(uploadFile.getUserId());
        vo.setFileName(uploadFile.getFileName());
        vo.setFilePath(uploadFile.getFilePath());
        vo.setFileUrl(uploadFile.getFileUrl());
        vo.setFileSize(uploadFile.getFileSize());
        vo.setFileType(uploadFile.getFileType());
        vo.setFileExtension(uploadFile.getFileExtension());
        vo.setBucketName(uploadFile.getBucketName());
        vo.setObjectName(uploadFile.getObjectName());
        vo.setUploadType(uploadFile.getUploadType());
        vo.setUploadSource(uploadFile.getUploadSource());
        vo.setMd5Hash(uploadFile.getMd5Hash());
        vo.setSha256Hash(uploadFile.getSha256Hash());
        vo.setIsImage(uploadFile.getIsImage());
        vo.setImageWidth(uploadFile.getImageWidth());
        vo.setImageHeight(uploadFile.getImageHeight());
        vo.setStatus(uploadFile.getStatus());
        vo.setDownloadCount(uploadFile.getDownloadCount());
        vo.setViewCount(uploadFile.getViewCount());
        vo.setExpireTime(uploadFile.getExpireTime());
        vo.setCreateTime(uploadFile.getCreateTime());
        vo.setUpdateTime(uploadFile.getUpdateTime());
        
        return vo;
    }

}
